package com.example.demo.filter;

import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.isAlreadyRouted;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.serviceregistry.Registration;
import org.springframework.cloud.client.serviceregistry.ServiceRegistry;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.context.annotation.Lazy;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

@SuppressWarnings("SpringJavaAutowiredFieldsWarningInspection")
@Component
@Slf4j
public class DeregisterInstanceGatewayFilter implements GatewayFilter, Ordered {

  @Autowired
  @Lazy
  private ServiceRegistry serviceRegistry;

  @Autowired
  @Lazy
  private Registration registration;

  public DeregisterInstanceGatewayFilter() {
    log.info("DeregisterInstanceGatewayFilter 启用");
  }

  @Override
  public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
    if (isAlreadyRouted(exchange)) {
      return chain.filter(exchange);
    }

    log.info("deregister serviceName:{}, ip:{}, port:{}",
        registration.getServiceId(),
        registration.getHost(),
        registration.getPort());

    try {
      serviceRegistry.deregister(registration);
    }
    catch (Exception e) {
      log.error("deregister error", e);
    }

    ServerHttpResponse response = exchange.getResponse();
    response.getHeaders().setContentType(MediaType.APPLICATION_JSON_UTF8);
    DataBuffer bodyDataBuffer = response.bufferFactory().wrap("{}".getBytes());
    response.setStatusCode(HttpStatus.OK);
    return response.writeWith(Mono.just(bodyDataBuffer));
  }

  @Override
  public int getOrder() {
    return 0;
  }
}
